
#include "xen_mmc_mng.hpp"

#include	"HsimIncl.h"


xen_mmc_mng_ptr xen_mmc_mng::_instance;
boost::mutex xen_mmc_mng::_singletone_lock;

xen_mmc_mng::xen_mmc_mng()
{
	PDBG("create xen_mmc_mng!!\n");
}

xen_mmc_mng::~xen_mmc_mng()
{
	PDBG("delete xen_mmc_mng!!\n");
}

xen_mmc_mng_ptr xen_mmc_mng::instance()
{
    if (_instance.use_count() == 0) {   /* FIXME */
        boost::mutex::scoped_lock scoped_lock(_singletone_lock);
        if (_instance.use_count() == 0) {
            _instance.reset(new xen_mmc_mng());
        }
    }
    return _instance;
}

void xen_mmc_mng::recv_mmc(int id, std::string& msg)
{
	PDBG(">>>> id(%d) wait to unlock mutux !!!!\n", id);
	boost::mutex::scoped_lock scoped_lock(_list_lock);
	
	if (_jobs.empty()) {
		PDBG(">>>>>>>>> job list is empty!!!!!\n");
		return ;
	}

	while (1) {
		PDBG("id(%d), flag(%d)\n", (*_jobs.begin())._id, (*_jobs.begin())._flag);

		if ((*_jobs.begin())._id == id && (*_jobs.begin())._flag == 1)
		{
			PDBG("BREAK >> id(%d), flag(%d)\n", (*_jobs.begin())._id, (*_jobs.begin())._flag);
		} else {
			PDBG("id(%d) wait to recevied msg!!!!\n", id);
			_list_cond.wait(_list_lock);
			PDBG("notifed from push_mmc!!!\n");
			break;
		}
	}

	job_iterator iter = _jobs.begin();
	for (; iter != _jobs.end(); iter++) {
		PDBG(">> check: id(%d), flag(%d)\n", (*iter)._id, (*iter)._flag);
		if((*iter)._id == id && (*iter)._flag == 1) {
			msg.assign((*iter)._data);
			_jobs.erase(iter);
			PDBG("find msg !!!!\n");
			break;
		}
	}
}

void xen_mmc_mng::push_mmc(const std::string& msg)
{

	PDBG("++++++++++++ wait to unlock mutex !!!\n");
	boost::mutex::scoped_lock scoped_lock(_list_lock);
	job_iterator iter = _jobs.begin();
	for (; iter != _jobs.end(); iter++) {
		if((*iter)._flag == 0) {
			(*iter)._data.assign(msg);
			(*iter)._flag = 1;
			PDBG("++++++++++++ id(%d) recevied msg!!!\n", (*iter)._id);
			_list_cond.notify_one();
			return ;
		}
	}
	PDBG("++++++++++++ who are you!!!!!!!!!!!\n");
	PDBG("++++++++++++ are you alarm ??????????\n");
}

void xen_mmc_mng::send_mmc(int id, const std::string& msg)
{
	ClientServerIPC 	mmc;
	job_t job;

	memset((xc8 *)&mmc, 0, sizeof(mmc));
	mmc.overflow = uFalse;
	mmc.next = uFalse;
	mmc.PacketNo = 1;
	mmc.usrIndex = 0;
	sprintf(mmc.usrName, "%s", "xener");
	mmc.usrType = CLI_USER;
	mmc.dataType = TEXT_CMD;

	memcpy(mmc.DataUnit, msg.c_str(), msg.length());
	printf("\n++++++++++++++++++++++++++++++++\n");
	printf("userIndex: %d, usrName: %s\n", mmc.usrIndex, mmc.usrName);
	printf("SEND DATA: %s\n", mmc.DataUnit);
	printf("\n++++++++++++++++++++++++++++++++\n");

	{ 
        boost::mutex::scoped_lock scoped_lock(_send_lock);
		job._id = id;
		job._flag = 0;
		_jobs.push_back(job);
		SendMsgProc(UserInputStr, (xc8 *) &mmc, sizeof(mmc), g_HsmbEntId);
	}
	return ;
}

